import { uploadWholeUrl } from '@/api/system/upload';
import { useFansStore } from '@/store/fans';
import { msg } from '@/utils/msg';
import Compressor from 'compressorjs';
import { refreshToken } from '@/api/reauth';
import { report } from '@/utils/exception';

const fansStore = useFansStore();
const platform = uni.getSystemInfoSync().uniPlatform; // 平台
const maxImgSize = 0.8 * 1024 * 1024; // 图片压缩阈值(单位MB)

/**
 * 图片上传到服务器（小程序）
 * @param imgPath 文件路径
 * @param fileName 文件名
 * @returns
 */
const uploadImgToServerByWeixin = (imgPath: string, fileName: string) =>
  new Promise((resolve, reject) => {
    uni.uploadFile({
      url: uploadWholeUrl,
      filePath: imgPath,
      name: 'file',
      formData: {
        key: fileName,
      },
      header: {
        Authorization: 'Bearer ' + fansStore.fansinfo.token,
      },
      success: (res) => {
        if (res.statusCode == 200 && res.errMsg == 'uploadFile:ok') {
          const result = JSON.parse(res.data);
          if (result.code == 200) {
            return resolve(result.data.url);
          }

          if (result.code == 401) {
            return refreshToken()
              .then(() => {
                uploadImgToServerByWeixin(imgPath, fileName)
                  .then((resp) => resolve(resp))
                  .catch((err) => reject(err));
              })
              .catch((error) => {
                report(error);
                if (error.msg) {
                  reject(error.msg);
                } else {
                  reject(error);
                }
              });
          }

          msg.error(result.msg);
          reject(result.msg);
        } else {
          console.error(res);
          msg.error('图片上传服务器失败');
          reject('图片上传服务器失败');
        }
      },
      fail: (err) => {
        reject(err.errMsg);
      },
    });
  });

/**
 * 图片上传到服务器（h5）
 * @param imgFile 图片文件
 * @param fileName 文件名
 * @returns
 */
const uploadImgToServerByH5 = (imgFile: File, fileName: string) =>
  new Promise((resolve, reject) => {
    uni.uploadFile({
      url: uploadWholeUrl,
      file: imgFile,
      formData: {
        key: fileName,
      },
      header: {
        Authorization: 'Bearer ' + fansStore.fansinfo.token,
      },
      success: (res) => {
        if (res.statusCode == 200 && res.errMsg == 'uploadFile:ok') {
          const result = JSON.parse(res.data);
          if (result.code == 200) {
            return resolve(result.data.url);
          }

          if (result.code == 401) {
            return refreshToken()
              .then(() => {
                uploadImgToServerByH5(imgFile, fileName)
                  .then((resp) => resolve(resp))
                  .catch((err) => reject(err));
              })
              .catch((error) => {
                report(error);
                if (error.msg) {
                  reject(error.msg);
                } else {
                  reject(error);
                }
              });
          }

          msg.error(result.msg);
          reject(result.msg);
        } else {
          console.error(res);
          msg.error('图片上传服务器失败');
          reject('图片上传服务器失败');
        }
      },
      fail: (err) => {
        reject(err.errMsg);
      },
    });
  });

/**
 * 图片压缩
 * @param imgFile 图片文件
 * @returns
 */
const compressImg = (imgFile: File) =>
  new Promise((resolve, reject) => {
    // h5压缩
    new Compressor(imgFile, {
      quality: 0.8, // 压缩质量
      maxWidth: 2500, // 最大宽度
      maxHeight: 2000, // 最大高度
      success(res) {
        // console.log('压缩成功', res);
        resolve(res);
      },
      error(err) {
        reject(err.message);
      },
    });
  });

/**
 * 获取图片文件后缀
 * @param type 图片文件类型
 * @returns
 */
const getImgExt = (type: string) => {
  switch (type) {
    case 'image/jpeg':
      return '.jpg';
    case 'image/png':
      return '.png';
    case 'image/gif':
      return '.gif';
    case 'image/webp':
      return '.webp';
    default:
      return '.jpg';
  }
};

const getFilename = (filePath: string, imgType: string) => {
  return filePath.substring(filePath.lastIndexOf('/') + 1) + getImgExt(imgType);
};

const uploadImg = (imgNum = 1) => {
  let imgUrls: string[] = [];

  return new Promise((resolve, reject) => {
    uni.chooseImage({
      count: imgNum,
      sizeType: ['compressed'],
      sourceType: ['album', 'camera'],
      success: (res) => {
        const filePaths = res.tempFilePaths as string[];
        const fileTmps = res.tempFiles as File[];
        const fileNum = fileTmps.length;

        msg.loading('上传中');
        switch (platform) {
          case 'mp-weixin':
            // 微信小程序上传
            filePaths.forEach(async (imgPath: string, index: number) => {
              // let fileSize = fileTmps[index].size;
              let fileName = getFilename(imgPath, fileTmps[index].type);
              try {
                let imgUrl = (await uploadImgToServerByWeixin(imgPath, fileName)) as string;
                imgUrls.push(imgUrl);
                if (imgUrls.length == fileNum) {
                  msg.hideLoading();
                  resolve(imgUrls);
                }
              } catch (err) {
                reject(err);
              }
            });
            break;

          case 'web':
            // h5上传
            fileTmps.forEach(async (imgFile: File, index: number) => {
              let fileName = getFilename(filePaths[index], imgFile.type);
              let fileSize = imgFile.size;
              if (fileSize > maxImgSize) {
                try {
                  imgFile = (await compressImg(imgFile)) as File;
                  console.log(
                    '压缩率：' + ((imgFile.size / fileSize) * 100).toFixed(2) + '%',
                    '文件大小：' + (imgFile.size / 1024).toFixed(2) + 'kb'
                  );
                } catch (err) {
                  reject(err);
                }
              }

              try {
                let imgUrl = (await uploadImgToServerByH5(imgFile, fileName)) as string;
                imgUrls.push(imgUrl);
                if (imgUrls.length == fileNum) {
                  msg.hideLoading();
                  resolve(imgUrls);
                }
              } catch (err) {
                reject(err);
              }
            });
            break;
        }
      },
    });
  });
};

export { uploadImgToServerByH5, uploadImgToServerByWeixin, uploadImg };
